package com.eelpo.framework.socket.session;

import java.net.SocketAddress;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelConfig;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelState;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.DownstreamChannelStateEvent;
import org.jboss.netty.channel.DownstreamMessageEvent;

/**
 * socket 会话类
 * 
 * @author <a href="mailto:whz-work@163.com">汪洪州</a>
 * 
 * @since 1.0 Create on May 30, 2012
 */
public class SocketSession implements Channel {

	protected Long playerId;
	protected String account;
	protected boolean logined;
	protected final Channel channel;

	public SocketSession(Channel channel) {
		this.channel = channel;
	}

	public Long getPlayerId() {
		return playerId;
	}

	public String getAccount() {
		return account;
	}

	public boolean isLogined() {
		return logined;
	}

	public void login(Long playerId, String account) {
		this.playerId = playerId;
		this.account = account;
		SocketSessionCache.addSession(playerId, this);
	}

	public void logout() {
		SocketSessionCache.removeSession(playerId);
	}

	public void joinSessionGroup(String name) {
		SocketSessionCache.joinSessionGroup(name, this);
	}

	public void leaveSessionGroup(String name) {
		SocketSessionCache.leaveSessionGroup(name, this);
	}

	public void writeWithoutFuture(Object message) {
		writeWithoutFuture(message, null);
	}

	public void writeWithoutFuture(Object message, SocketAddress remoteAddress) {
		getPipeline().sendDownstream(new DownstreamMessageEvent(channel, Channels.succeededFuture(channel), message, remoteAddress));
	}

	public void bindWithoutFuture(SocketAddress localAddress) {
		getPipeline().sendDownstream(new DownstreamChannelStateEvent(channel, Channels.succeededFuture(channel), ChannelState.BOUND, localAddress));
	}

	public void unbindWithoutFuture() {
		getPipeline().sendDownstream(new DownstreamChannelStateEvent(channel, Channels.succeededFuture(channel), ChannelState.BOUND, null));
	}

	public void connectWithoutFuture(SocketAddress remoteAddress) {
		getPipeline().sendDownstream(new DownstreamChannelStateEvent(channel, Channels.succeededFuture(channel), ChannelState.CONNECTED, remoteAddress));
	}

	public void disconnectWithoutFuture() {
		getPipeline().sendDownstream(new DownstreamChannelStateEvent(channel, Channels.succeededFuture(channel), ChannelState.CONNECTED, null));
	}

	public void closeWithoutFuture() {
		getPipeline().sendDownstream(new DownstreamChannelStateEvent(channel, Channels.succeededFuture(channel), ChannelState.OPEN, Boolean.FALSE));
	}

	public void setInterestOpsWithoutFuture(int interestOps) {
		getPipeline().sendDownstream(new DownstreamChannelStateEvent(channel, Channels.succeededFuture(channel), ChannelState.INTEREST_OPS, Integer.valueOf(interestOps)));
	}

	public void setReadableWithoutFuture(boolean readable) {
		if (readable) {
			setInterestOpsWithoutFuture(getInterestOps() | OP_READ);
		} else {
			setInterestOpsWithoutFuture(getInterestOps() & ~OP_READ);
		}
	}

	@Override
	public Integer getId() {
		return channel.getId();
	}

	@Override
	public ChannelFactory getFactory() {
		return channel.getFactory();
	}

	@Override
	public Channel getParent() {
		return channel.getParent();
	}

	@Override
	public ChannelConfig getConfig() {
		return channel.getConfig();
	}

	@Override
	public ChannelPipeline getPipeline() {
		return channel.getPipeline();
	}

	@Override
	public boolean isOpen() {
		return channel.isOpen();
	}

	@Override
	public boolean isBound() {
		return channel.isBound();
	}

	@Override
	public boolean isConnected() {
		return channel.isConnected();
	}

	@Override
	public SocketAddress getLocalAddress() {
		return channel.getLocalAddress();
	}

	@Override
	public SocketAddress getRemoteAddress() {
		return channel.getRemoteAddress();
	}

	@Override
	public ChannelFuture write(Object message) {
		return channel.write(message);
	}

	@Override
	public ChannelFuture write(Object message, SocketAddress remoteAddress) {
		return channel.write(message, remoteAddress);
	}

	@Override
	public ChannelFuture bind(SocketAddress localAddress) {
		return channel.bind(localAddress);
	}

	@Override
	public ChannelFuture connect(SocketAddress remoteAddress) {
		return channel.connect(remoteAddress);
	}

	@Override
	public ChannelFuture disconnect() {
		return channel.disconnect();
	}

	@Override
	public ChannelFuture unbind() {
		return channel.unbind();
	}

	@Override
	public ChannelFuture close() {
		return channel.close();
	}

	@Override
	public ChannelFuture getCloseFuture() {
		return channel.getCloseFuture();
	}

	@Override
	public int getInterestOps() {
		return channel.getInterestOps();
	}

	@Override
	public boolean isReadable() {
		return channel.isReadable();
	}

	@Override
	public boolean isWritable() {
		return channel.isWritable();
	}

	@Override
	public ChannelFuture setInterestOps(int interestOps) {
		return channel.setInterestOps(interestOps);
	}

	@Override
	public ChannelFuture setReadable(boolean readable) {
		return channel.setReadable(readable);
	}

	@Override
	public int compareTo(Channel o) {
		return channel.compareTo(o);
	}
}
